package com.sky.module.system.role.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.module.suppot.datatrace.util.ContentUtil;
import com.sky.module.system.datatrace.dao.DataTraceMapper;
import com.sky.module.system.datatrace.domain.entity.DataTracerEntity;
import com.sky.module.system.role.dao.RoleMapper;
import com.sky.module.system.role.domain.entity.Role;
import com.sky.module.system.role.domain.vo.RoleQueryVo;
import com.sky.module.system.role.service.RoleService;
import com.sky.module.system.user.dao.UserMapper;
import com.sky.module.system.user.domain.entity.User;
import com.sky.module.system.utils.RequestInfoUtils;
import org.apache.tomcat.jni.Local;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zsg
 * @since 2023-02-20
 */
@Transactional
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DataTraceMapper dataTraceMapper;

    @Override
    public IPage<Role> findRoleListByPage(IPage<Role> page, RoleQueryVo roleQueryVo) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!ObjectUtils.isEmpty(roleQueryVo.getRoleName()), Role::getRoleName, roleQueryVo.getRoleName());
//        排序
        queryWrapper.orderByAsc(Role::getId);
//        根据用户id查询用户信息
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();


//        User user = userMapper.selectById(roleQueryVo.getUserId());
//
//        adimn !=1 就是非管理员
        if (user == null && !ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() != 1) {
//            非管理员只能查询自己创建的角色
            queryWrapper.eq(Role::getCreateUser, roleQueryVo.getUserId());

        }
        return baseMapper.selectPage(page, queryWrapper);
    }


    /***
     * @description 检查角色是否被分配
     * @param id
     * @return boolean
     * @date 2023/2/23 1:08
     *
     */
    @Override
    public boolean hasRoleCount(Long id) {
        return baseMapper.getRoleCountByRoleId(id) > 0;
    }

    @Override
    public boolean removeByRoleId(Long id) {
//         删除多对多关系 根据角色id删除 角色权限 中间表的数据  TODO 用户角色中间表的数据
        baseMapper.deleteRolePermissionByRoleId(id);

        // 删除角色信息
        return baseMapper.deleteById(id) > 0;
    }

    /***
     * @description 保存角色权限信息
     * @param roleId
     * @param permissionIds
     * @return boolean
     * @date 2023/2/23 19:10
     *
     */
    @Override
    public boolean saveRolePermission(Long roleId, List<Long> permissionIds) {
//        删除权限关系
        baseMapper.deleteRolePermissionByRoleId(roleId);

//        保存角色权限关系
        return baseMapper.saveRolePermission(roleId, permissionIds) > 0;
    }

    /***
     * @description TODO
     * @param userId
     * @return java.util.List<java.lang.Long>
     * @date 2023/2/24 2:18
     *
     */
    @Override
    public List<Long> findRoleIdByUserId(Long userId) {
        return baseMapper.findRoleIdByUserId(userId);
    }

    /***
     * @description 保存角色信息，同时做数据变更记录
     * @param role
     * @return boolean
     * @date 2023/3/9 0:50
     *
     */
    @Override
    public boolean saveRole(Role role) {
        // 获取注解上的值
        final String tableName = ContentUtil.getTableName(role);
//        TODO  下沉到manager层
        baseMapper.insert(role);

        LocalDateTime now = LocalDateTime.now();
//        // 获取最基本的信息
        String ip = RequestInfoUtils.getIP();
        User user = RequestInfoUtils.getUser();
        String userAgent = RequestInfoUtils.getUserAgent();
        DataTracerEntity dataTracerEntity = DataTracerEntity.builder()
                .tableName(tableName)
                .updateTime(now)
                .createTime(now)
                .diffNew("")
                .diffOld("")
                .content("新增角色信息")
                .ip(ip)
                .userAgent(userAgent.toString())
                .recordId(role.getId())
                .userId(user.getId())
                .userName(user.getUsername())
                .build();

        dataTraceMapper.insert(dataTracerEntity);
//                .userType(user.)
        return true;
    }

    /***
     * @description 同时记录数据变更记录
     * @param role
     * @return boolean
     * @date 2023/3/9 1:11
     *
     */
    @Override
    public boolean updateRoleById(Role role) {
        // 进行属性对比
        Role oldRole = baseMapper.selectById(role.getId());
        final String tableName = ContentUtil.getTableName(role);
        final Map<String, String> content = ContentUtil.getContent(oldRole, role);
        String oldStr = content.get("oldStr");
        String newStr = content.get("newStr");
        User user = RequestInfoUtils.getUser();
        String userAgent = RequestInfoUtils.getUserAgent();
        final String ip = RequestInfoUtils.getIP();
        final LocalDateTime now = LocalDateTime.now();
        final DataTracerEntity dataTracerEntity = DataTracerEntity.builder()
                .userId(user.getId())
                .userName(user.getUsername())
                .recordId(role.getId())
                .userAgent(userAgent)
                .ip(ip)
                .diffOld(oldStr)
                .diffNew(newStr)
                .content("修改角色信息")
                .tableName(tableName)
                .createTime(now)
                .updateTime(now)
                .build();
        // 获取日志信息
        dataTraceMapper.insert(dataTracerEntity);
        baseMapper.updateById(role);
        return true;
    }
}
